package view;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

import server.Log;
import server.RulesTableType;


/**
 * Class is responsible for frame with all filtering options:
 * 					by IP/port/direction
 * 					by protocol
  * Frame contains: text field for histroy days inserting.
 * 					standart buttons.
 * 					for IP filtering: text boxes for IP, port, direction
 * 					for protocol filtering: text box for protocol
 */
public class LoggerFilterFrame extends AbstractCommonFrame
{ 
	/**
	 * Serial version ID - for serialization
	 */
	private static final long serialVersionUID = 36785838378185037L;
	
	/**
	 * Current shown filer frame.
	 */
	private static LoggerFilterFrame currentFilterFrame = null;
	
	/**
	 * Filter chosen type.
	 */
	public static FilterType currentType = FilterType.ALL;
	
	/**
	 * Possible directions for filtering.
	 */
	private static String[] dirStrings = {"",RulesTableType.IN.toString(),RulesTableType.OUT.toString()};

	/**
	 * Possible filters.
	 */
	private static FilterType[] filterStrings = {FilterType.ALL,
												FilterType.IP,
												FilterType.PROTOCOL};
	
	/**
	 * Filter options radio buttons.
	 */
	private static JRadioButton[] filterButtons = new JRadioButton[filterStrings.length];
	
	/**
	 * History depth text field.
	 */
	private static JTextField numOfDaysField  = null;
	
	/**
	 * Protocol text field.
	 */
	private static JTextField protocolTextField = null;
	/**
	 * Port text field.
	 */
	private static JTextField portTextField = null;
	/**
	 * IP text field.
	 */
	private static JTextField ipTextField = null;
	/**
	 * Directions combo box.
	 */
	private static JComboBox directionField = null;
	
	/** 
	 * Panel for 'all' filter filters and parameters.
	 */
	private JPanel generalPanel = null; 
	/** 
	 * Panel for 'protocol' filter filters and parameters.
	 */
	private JPanel protocolPanel = null;
	/** 
	 * Panel for 'IP' filter filters and parameters.
	 */
	private JPanel ipPanel = null;
	
	/**
	 * Last opened panel for parameters
	 */
	private JPanel lastOpenedPanel = null;

	/**
	 * C'tor - create the frame with specified size/
	 * Creates panels for ALL/IP/PROTOCOL filters
	 * Add radio buttons for filters.
	 */
	public LoggerFilterFrame()
	{
		/* Window's characteristics */
		super("Filter Options");
		setSize(400, 150);
		setLayout(new BorderLayout());
		
		/* Panel for history options */
		JPanel historyPanel = new JPanel(new BorderLayout());
		
		JLabel historyLabel = new JLabel("Logger hitory (in days):");
		historyPanel.add(historyLabel, BorderLayout.NORTH);

		/* To the history field tha current history is set */
		numOfDaysField  = new JTextField();
		if (Settings.historyDepth != -1 )
		{
			numOfDaysField.setText(Long.toString(Settings.historyDepth));
		}
		historyPanel.add(numOfDaysField, BorderLayout.CENTER);		
		add(historyPanel, BorderLayout.NORTH);
		
		/* Panel for filter options and parameters */
		generalPanel = new JPanel(new GridLayout(1,2));
		
		/* Panel for filter options */
		JPanel filter = new JPanel(new GridLayout(4,1));
		JLabel filterLabel = new JLabel("Filter options:");
		filter.add(filterLabel);
		
		/* Radio buttons */
		ButtonGroup filterTypeGroup = new ButtonGroup();
		
		for(int i = 0; i < filterStrings.length; i++)
		{
			filterButtons[i] = new JRadioButton();
			filterButtons[i].setText(filterStrings[i].toString());
			filterTypeGroup.add(filterButtons[i]);
			filter.add(filterButtons[i]);
			/* New options are shown for each radio buttons */
			filterButtons[i].addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e)
				{
					for(int i = 0; i < filterButtons.length; i++)
					{
						if(filterButtons[i].isSelected())
						{
							/* Delete last panel */
							if(lastOpenedPanel != null)
							{
								lastOpenedPanel.setVisible(false);
								generalPanel.remove(lastOpenedPanel);
							}
							
							/* Add new panel and remember options */
							switch(filterStrings[i])
							{
							case PROTOCOL:
								generalPanel.add(protocolPanel);
								lastOpenedPanel = protocolPanel;
								protocolPanel.setVisible(true);
								currentType = FilterType.PROTOCOL;
								break;
							case IP:
								generalPanel.add(ipPanel);
								lastOpenedPanel = ipPanel;
								ipPanel.setVisible(true);
								currentType = FilterType.IP;
								break;
							case ALL:
								currentType = FilterType.ALL;
								lastOpenedPanel = null;
								break;
							}
						}
					}/*for(int i = 0; i < filterButtons.length; i++)*/
					currentFilterFrame.setVisible(true);
				}
			});
		}
		filterButtons[0].setSelected(true);
		generalPanel.add(filter);
		
		add(generalPanel, BorderLayout.CENTER);

		/* Create panels for the view */
		createParametersPanels();
		
		/* Standart buttons */
	   addStandartButtons();
	    
	    /* Store the current open window */
	    currentFilterFrame = this;
		setLocationRelativeTo(null);
	}


	/**
	 * Creates the panels for each filter (ALL/IP/PROTOCOL).
	 */
	private void createParametersPanels()
	{		
		/* Parameters for protocol panel */
		protocolPanel = new JPanel(new GridLayout(3,2));	

		JLabel protocolLabel = new JLabel("Protocol:");
		protocolPanel.add(protocolLabel);
		protocolTextField = new JTextField(Settings.filterProtocol);
		protocolPanel.add(protocolTextField);
		
		/* Parameters for IP panel */
		ipPanel = new JPanel(new GridLayout(3,2));	

		JLabel ipLabel = new JLabel("IP:");
		ipPanel.add(ipLabel);
		ipTextField = new JTextField();
		ipPanel.add(ipTextField);
		JLabel portLabel = new JLabel("Port:");
		ipPanel.add(portLabel);
		portTextField = new JTextField();
		ipPanel.add(portTextField);
		JLabel dirLabel = new JLabel("Direction:");
		ipPanel.add(dirLabel);
		directionField = new JComboBox(dirStrings);
		ipPanel.add(directionField);
	}

	/**
	 * The action performed by finish button pressing.
	 */
	protected void finishAction()
	{
		/* Clear the previous filter options */
		Settings.historyDepth 	= null;
		Settings.filterProtocol = null;
		Settings.filterIP 		= null;
		Settings.filterPort  	= null;
		Settings.filterDir 		= null;
		
		/* Add new panel and remember options */
		switch(currentType)
		{
		case PROTOCOL:
			String protocol = protocolTextField.getText();
			if (!protocol.equals(""))
			{
				Settings.filterProtocol = protocol;
			}
			Settings.currentFilterType = FilterType.PROTOCOL;
			break;
		case IP:
			/*get IP*/
			String ip = ipTextField.getText();
			if (!ip.equals(""))
			{
				Settings.filterIP = ip;
			}
			
			/*get Port*/
			String port = portTextField.getText();
			if(!port.equals(""))
			{
				try 
				{
					Settings.filterPort = Integer.parseInt(port);
				} 
				catch (NumberFormatException e)
				{
					ErrorFrame.AddError("Illegal port number is entered (need natural number)", 
										 currentFilterFrame);
					return;
				}						
			}

			/* get Direction */
			String dir = (String) directionField.getSelectedItem();
			if (dir.equals(RulesTableType.IN.toString()))
			{
				Settings.filterDir = Log.directOpt.IN;
			}
			else if(dir.equals(RulesTableType.OUT.toString()))
			{
				Settings.filterDir = Log.directOpt.OUT;
			}					
			Settings.currentFilterType = FilterType.IP;
			break;
		case ALL:
			Settings.currentFilterType = FilterType.ALL;
			break;
		}
		
		/* Get he number of history days */
		try 
		{
			String days = numOfDaysField.getText();
			if (days == null || days.equals(""))
			{
				Settings.historyDepth = null;
			}
			else
			{ 
				Settings.historyDepth =  Integer.parseInt( numOfDaysField.getText());
			}
		}
		catch (NumberFormatException e)
		{
			ErrorFrame.AddError("Illegal days number is entered (need natural number)", 
								currentFilterFrame);
			return;	
		}
		
		/* Rebuild the tables according to the new options */
		LoggerTable.currentLoggerTable.buildTable();
		LoggerGlobalTable.currentLoggerGlobalTable.buildTable();
		currentFilterFrame.dispose();
	}
		
}
